/*
 __  __             ______    _ _ _             
|  \/  |           |  ____|  | (_) |            
| \  / | __ _ _ __ | |__   __| |_| |_ ___  _ __ 
| |\/| |/ _` | '_ \|  __| / _` | | __/ _ \| '__|
| |  | | (_| | |_) | |___| (_| | | || (_) | |   
|_|  |_|\__,_| .__/|______\__,_|_|\__\___/|_|   
             | |                                
             |_|     
			 
The MapEditor Project
Created by JariZ & Scripts18
Based on SparkyMcSparks' HideNSeek
(c) JariZ.nl 2011
This a open-source project. for more information see LICENSE.TXT
*/

// MapEditor Core

#include maps\mp\_utility;
#include common_scripts\utility;
#include maps\mp\gametypes\_hud_util;
#include maps\mp\gametypes\me_assets;
#include maps\mp\gametypes\me_randomweapon;
#include maps\mp\gametypes\me_turrets;
#include library\json;

main()
{
		iPrintLn( "____________________");
        iPrintLn( "Map Editor Beta" );
        iPrintLn( "MapEditor@jariz.nl " );
        iPrintLn( "Scripts And JariZ" );
		iPrintLn( "____________________");
		
		
		
        if( GetDvar( "mapname" ) == "mp_background" )
        {
                return;
        }
       
        if( !mapSupport() )
        {
                error( "Could not find any available models to use." );
                maps\mp\gametypes\_callbacksetup::AbortLevel();
                return;
        }
		
		level.saveFile = generateLog();
		MapEditor_StartLogSystem();
		
		MapEditor_LoadAssets();
		
        collMapListGenerate();
        if( GetDvarInt( "scr_me_maxusablemodels" ) < 1 )
        {
                SetDvar( "scr_me_maxusablemodels", 300 );
        }
        level.MAX_USUABLE_MODELS = GetDvarInt( "scr_me_maxusablemodels" );
		level.MAX_COLL_MODELS = level.collMapModels.size;
		
        onPrecacheGameModels();
        maps\mp\gametypes\_globallogic::init();
        maps\mp\gametypes\_callbacksetup::SetupCallbacks();
        maps\mp\gametypes\_globallogic::SetupCallbacks();
        maps\mp\gametypes\_globallogic_utils::registerTimeLimitDvar( "tdm", 10, 0, 1440 );
        maps\mp\gametypes\_globallogic_utils::registerScoreLimitDvar( "tdm", 7500, 0, 50000 );
        maps\mp\gametypes\_globallogic_utils::registerRoundLimitDvar( "tdm", 1, 0, 10 );
        maps\mp\gametypes\_globallogic_utils::registerRoundWinLimitDvar( "tdm", 0, 0, 10 );
        maps\mp\gametypes\_globallogic_utils::registerNumLivesDvar( "tdm", 0, 0, 10 );
        maps\mp\gametypes\_weapons::registerGrenadeLauncherDudDvar( level.gameType, 10, 0, 1440 );
        maps\mp\gametypes\_weapons::registerThrownGrenadeDudDvar( level.gameType, 0, 0, 1440 );
        maps\mp\gametypes\_weapons::registerKillstreakDelay( level.gameType, 0, 0, 1440 );
        maps\mp\gametypes\_globallogic::registerFriendlyFireDelay( level.gameType, 15, 0, 1440 );
		
        level.gametype = "tdm";
        level.fullGameTypeName = "tdm";
        level.teamBased = true;
        level.overrideTeamScore = true;
        level.onStartGameType = ::onStartGameType;
        level.onSpawnPlayer = ::onSpawnPlayer;
        level.onSpawnPlayerUnified = ::onSpawnPlayerUnified;
        level.onDeadEvent = ::onDeadEvent;
        level.onTimeLimit = ::onTimeLimit;
        level.onRoundEndGame = ::onRoundEndGame;
		level.onPlayerKilled = ::onPlayerKilled;
        level.endGameOnScoreLimit = false;
        setscoreboardcolumns( "kills", "deaths", "kdratio", "assists" );
        level thread onPlayerConnect();
}

MapEditor_StartLogSystem()
{
	if(!issubstr(getdvar("g_log"), "savedmaps"))
	{
		old_logfile = getdvar("logfile");
		g_logsync = getdvar("g_logSync");
		timestamp = getdvar("g_logTimeStampInSeconds");
		setdvar("logfile", "1");
		setdvar("g_logSync", "1");
		setdvar("g_logTimeStampInSeconds", "0");
		setdvar("g_log", level.saveFile);
		map_restart();
	}
}
 
MapEditor_LoadAssets()
{
	precacheMenu( "me_cmd" );
	precacheMenu( "me_start" );
	precacheMenu( "me_controls" );
	precacheMenu( "me_switchto" );
	precacheModel( "mounted_ger_mg42_mg" );
	precacheShader( "mapeditor_logo" );
}

MapEditor_HUD()
{
		self endon("disconnect");
		Icon = NewHudElem();
        Icon.elemType = "icon";
        Icon.alignX = "right";
        Icon.alignY = "top";
        Icon.horzAlign = "right";
        Icon.vertAlign = "top";
        Icon.foreground = false;
        Icon.hideWhenInMenu = true;
        Icon.x = -40;
        Icon SetShader ( "mapeditor_logo" ,100,40 );
}
 
onStartGameType()
{
        SetClientNameMode( "manual_change" );
        SetDvar( "scr_teambalance", 0 );
        SetDvar( "scr_disable_cac", 1 );
        MakeDvarServerInfo( "scr_disable_cac", 1 );
        SetDvar( "scr_disable_weapondrop", 1 );
        SetDvar( "scr_game_perks", 0 );
        level.killstreaksenabled = 0;
        level.hardpointsenabled = 0;
        SetDvar( "xblive_privatematch", 0 );
        MakeDvarServerInfo( "xblive_privatematch", 0 );
        //maps\mp\gametypes\_globallogic_ui::setObjectiveHintText( "allies", "Map^1Editor ^7V1\nBy ^3Scripts18 ^7and ^3JariZ.nl" );
        //maps\mp\gametypes\_globallogic_ui::setObjectiveHintText( "axis", "Map^1Editor ^7V1\nBy ^3Scripts18 ^7and ^3JariZ.nl" );
        level.spawnMins = ( 0, 0, 0 );
        level.spawnMaxs = ( 0, 0, 0 );
        maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_allies_start" );
        maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_axis_start" );
        maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_tdm_spawn" );
        maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_tdm_spawn" );
        maps\mp\gametypes\_spawning::updateAllSpawnPoints();
        level.spawn_axis_start= maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_tdm_spawn_axis_start" );
        level.spawn_allies_start= maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_tdm_spawn_allies_start" );
        level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
        setMapCenter( level.mapCenter );
        spawnpoint = maps\mp\gametypes\_spawnlogic::getRandomIntermissionPoint();
        setDemoIntermissionPoint( spawnpoint.origin, spawnpoint.angles );
        allowed[ 0 ] = "tdm";
        level.displayRoundEndText = false;
        maps\mp\gametypes\_gameobjects::main( allowed );
        maps\mp\gametypes\_spawning::create_map_placed_influencers();
 
}

buildMode()
{
		self notify("me_buildmode");
        self TakeAllWeapons();
        self DisableWeapons();
        self AllowAds( false );
        self notify( "stop_ammo" );
        self SetClientDvars(
        "cg_thirdPerson", "1",
        "cg_thirdPersonAngle", "360",
        "cg_thirdPersonRange", "200" );
        self ClearPerks();
        self SetPerk( "specialty_quieter" );
        self SetPerk( "specialty_gpsjammer" );
        if( IsDefined( self.pers[ "myprop" ]  ) )
        {
                self.pers[ "myprop" ] Delete();
        }
		
		//modes
		if(self.pers["mode"] == "normal")
		{
			usableModelsKeys = GetArrayKeys( level.usableModels );
			self.pers[ "myprop" ] = spawn( "script_model", self.origin );
			self.pers[ "myprop" ].health = 10000;
			self.pers[ "myprop" ].owner = self;
			self.pers[ "myprop" ].angles = self.angles;
			self.pers[ "myprop" ].indexKey = RandomInt( level.MAX_USUABLE_MODELS );
			self.pers[ "myprop" ] SetModel( level.usableModels[ usableModelsKeys[ self.pers[ "myprop" ].indexKey ] ] );
		}
		else if(self.pers["mode"] == "turret") 
		{
			usableModelsKeys = GetArrayKeys( level.turretList );
			self.pers[ "myprop" ] = spawn( "script_model", self.origin );
			self.pers[ "myprop" ].health = 10000;
			self.pers[ "myprop" ].owner = self;
			self.pers[ "myprop" ].angles = self.angles;
			self.pers[ "myprop" ].indexKey = RandomInt( level.turretList.size );
			self.pers[ "myprop" ] SetModel( level.turretList[ usableModelsKeys[ self.pers[ "myprop" ].indexKey ] ] );
		}
		else if(self.pers["mode"] == "collmodel")
		{
			usableModelsKeys = GetArrayKeys( level.collMapModels );
			self.pers[ "myprop" ] = spawn( "script_model", self.origin );
			self.pers[ "myprop" ].health = 10000;
			self.pers[ "myprop" ].owner = self;
			self.pers[ "myprop" ].angles = self.angles;
			self.pers[ "myprop" ].indexKey = RandomInt( level.MAX_COLL_MODELS );
			self.pers[ "myprop" ] SetModel( level.collMapModels[ usableModelsKeys[ self.pers[ "myprop" ].indexKey ] ] );
		}
        self.pers[ "myprop" ] SetCanDamage( true );
        self.pers[ "myprop" ] thread detachOnDisconnect( self );
        self.pers[ "myprop" ] thread attachModel( self );
        self thread monitorKeyPress();
}

MapEditor_Save_Beta()
{
	iprintln("jariz wants to have your soul :)");
	//start log
	old_logfile = getdvar("logfile");
	g_logsync = getdvar("g_logSync");
	timestamp = getdvar("g_logTimeStampInSeconds");
	setdvar("logfile", "1");
	setdvar("g_logSync", "1");
	setdvar("g_logTimeStampInSeconds", "0");
	
	//We're trying to create our own serializer here,
	//This is really awesome and very simple to read
	//One more time I say trying, because black ops doesnt have a JSON library :P
	logprint("## The following data requires JSON to decode! ##");
	logprint("<MapEditorExportStart>");
	logprint("{");
	logprint(JSONValues("mapName", getdvar("mapname"), true));
	logprint(JSONValues("", getdvar("mapname"), true));
	logprint("</MapEditorExportStart>");
	
	
	//put dvars back where they were
	setdvar("logfile", old_logfile);
	setdvar("g_logSync", g_logsync);
	setdvar("g_logTimeStampInSeconds", timestamp);
	
	iprintln("[Map^1Editor] ^2Saved file to mods/mp_MapEditor/"+level.saveFile);
	
	if(getdvar("developer") == "1")
	{
		//iprintln("filenum = "+OpenFile("lulz.txt", "write"));
	}
}

generateLog()
{
	return "savedmaps/me_save_"+randomint(1000)+".me";
}

fpsMode()
{
    self takeallweapons();
	self EnableWeapons();
	self AllowAds( true );
	self SetClientDvars(
	"cg_thirdPerson", "0" );
	self ClearPerks();
	randomWeapon();
	self show();
    
	
	
	if( IsDefined( self.pers[ "myprop" ]  ) )
	{
		self.pers[ "myprop" ] Delete();
	}
}
 
detachOnDisconnect( player )
{
        player endon( "death" );
        player endon( "killed_player" );
        player waittill( "disconnect" );
        modelOrigin = self.origin;
        self Delete();
        PlayFX( getfx( "hider_killed" ), modelOrigin );
}
 
attachModel( player )
{
        player endon( "disconnect" );
        player endon( "killed_player" );
        player endon( "death" );
        self endon( "death" );
        for( ;; )
        {
                wait (0.01);
                if( self.origin != player.origin )
                {
                        self MoveTo( player.origin, 0.1 );
                }
        }
}
 
onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
{
	if( IsDefined( self.pers[ "myprop" ] ) )
	{
		self.pers[ "myprop" ] Delete();
	}
	if( sMeansOfDeath == "MOD_SUICIDE" )
	{
		return;
	}
}

onPlayerConnect()
{
        for(;;)
        {
                level waittill ( "connected", player );
                player thread onPlayerSpawned();
                player thread onJoinedTeam();
				player thread MapEditor_HUD();
        }
}
 
onSpawnPlayerUnified()
{
        maps\mp\gametypes\_spawning::onSpawnPlayer_Unified();
}
 
onSpawnPlayer()
{
		self.pers[ "mode" ] = "normal";
        pixbeginevent( "HNS:onSpawnPlayer" );
        self.usingObj = undefined;
        if( level.inGracePeriod )
        {
                spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_tdm_spawn_" + self.pers[ "team" ] + "_start" );
                if( !spawnPoints.size )
                {
                        spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_sab_spawn_" + self.pers[ "team" ] + "_start" );
                }
                if( !spawnPoints.size )
                {
                        spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( self.pers[ "team" ] );
                        spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
                }
                else
                {
                        spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
                }
        }
        else
        {
                spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( self.pers[ "team" ] );
                spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
        }
        self Spawn( spawnPoint.origin, spawnPoint.angles, "tdm" );
        pixendevent();
}
 
onJoinedTeam()
{
        self endon( "disconnect" );
        for(;;)
        {
                self waittill( "joined_team" );
				
                self SetClientDvars(
                        "cg_thirdPerson", "1",
                        "cg_thirdPersonAngle", "360",
                        "cg_thirdPersonRange", "200" );
        }
}
 
hns_endGame( winningTeam, endReasonText )
{
        if( IsDefined( winningTeam ) )
        {
                [[level._setTeamScore]]( winningTeam, [[level._getTeamScore]]( winningTeam ) + 1 );
        }
        thread maps\mp\gametypes\_globallogic::endGame( winningTeam, endReasonText );
}
 
hns_endGameWithKillcam( winningTeam, endReasonText )
{
        level thread maps\mp\gametypes\_killcam::startLastKillcam();
        hns_endGame( winningTeam, endReasonText );
}
 
onPlayerSpawned()
{
        self endon( "disconnect" );
        level endon ( "game_ended" );
       
        for(;;)
        {                      
                self waittill( "spawned_player" );
				self thread onMenuResponse();
				self openMenu( "me_start" );
                self thread menu();      
				self fpsMode();
				
				
				//i like to play around with stuff ^^
				
				//maps\mp\_credits::initCredits();
				//maps\mp\_credits::playCredits();
				
				//maps\mp\_ac130::init();
				//maps\mp\_ac130::ac130_attachPlayer( self );
				
        }
}

watchLog()
{
	level waittill ( "game_ended" );
	setdvar("g_log", "game_mp.log");
}
 
buttonHeldCheck( struct )
{
        self endon ( "disconnect" );
        self endon ( "death" );
        if( [[ struct.check ]]() )
        {
                if( struct.max > 0 )
                {
                        struct.value += struct.change_rate;
                }
                else
                {
                        struct.value -= struct.change_rate;
                }
        }
        else if( struct.value != 0 )
        {
                if( struct.value > 0 )
                {
                        struct.value -= struct.reset_rate;
                }
                else
                {
                        struct.value += struct.reset_rate;
                }
                if( abs( struct.value ) < struct.reset_rate )
                {
                        struct.value = 0;
                }
        }
        if( struct.max > 0 )
        {
                if( struct.value > struct.max )
                {
                        struct.value = struct.max;
                }
        }
        else
        {
                if( struct.value < struct.max )
                {
                        struct.value = struct.max;
                }
        }
}
 
onDeadEvent( team )
{
        if( team == "all" )
        {
                hns_endGameWithKillcam( game[ "defenders" ], game[ "strings" ][game[ "attackers" ]+"_eliminated" ] );
        }
        else if( team == game[ "attackers" ] )
        {
                hns_endGameWithKillcam( game[ "defenders" ], game[ "strings" ][game[ "attackers" ]+"_eliminated" ] );
        }
        else if( team == game[ "defenders" ] )
        {
                hns_endGameWithKillcam( game[ "attackers" ], game[ "strings" ][game[ "defenders" ]+"_eliminated" ] );
        }
}
 
onTimeLimit()
{
        if( level.teamBased )
        {
                hns_endGame( game[ "defenders" ], game[ "strings" ][ "time_limit_reached" ] );
        }
        else
        {
                hns_endGame( undefined, game[ "strings" ][ "time_limit_reached" ] );
        }
}
 
onEndGame( winningTeam )
{
        if( IsDefined( winningTeam ) && ( winningTeam == "allies" || winningTeam == "axis" ) )
        {
                [[ level._setTeamScore ]]( winningTeam, [[ level._getTeamScore ]]( winningTeam ) + 1 );
        }
}
 
onRoundEndGame( roundWinner )
{
        if( game[ "roundswon" ][ "allies" ] == game[ "roundswon" ][ "axis" ] )
        {
                winner = "tie";
        }
        else if( game[ "roundswon" ][ "axis" ] > game[ "roundswon" ][ "allies" ] )
        {
                winner = "axis";
        }
        else
        {
                winner = "allies";
        }
        return winner;
}
 
monitorKeyPress()
{
       
		self endon( "disconnect" );
 
        self endon( "killed_player" );
        self endon( "death" );
		self endon( "me_buildmode" ); //kill when buildmode restarts
        level endon( "game_ended" );
		
		
        usableModelsKeys = GetArrayKeys( level.usableModels );
        minZoom = 125;
        maxZoom = 525;
        zoomChangeRate = 5;
        self Hide();
        self.pers[ "myprop" ].rotateYaw_attack = SpawnStruct();
        self.pers[ "myprop" ].rotateYaw_attack.value = 0;
        self.pers[ "myprop" ].rotateYaw_attack.check = ::attackCheck;
        self.pers[ "myprop" ].rotateYaw_attack.max = -50;
        self.pers[ "myprop" ].rotateYaw_attack.change_rate = 1;
        self.pers[ "myprop" ].rotateYaw_attack.reset_rate = 50;
        self.pers[ "myprop" ].rotateYaw_ads = SpawnStruct();
        self.pers[ "myprop" ].rotateYaw_ads.value = 0;
        self.pers[ "myprop" ].rotateYaw_ads.check = ::adsCheck;
        self.pers[ "myprop" ].rotateYaw_ads.max = 50;
        self.pers[ "myprop" ].rotateYaw_ads.change_rate = 1;
        self.pers[ "myprop" ].rotateYaw_ads.reset_rate = 50;
        self.pers[ "myprop" ].angles = self.angles;
		
        for(;;)
        {
             wait ( 0.05 );
                if( self ActionSlotTwoButtonPressed() && IsDefined( self.pers[ "myprop" ] ) )
                    {
							self playLocalSound( "uin_alert_cash_register" );
							if(self.pers["mode"] == "normal")
							{
                                //spawn code by JariZ.nl                            
                                //get current model
                                model = level.usableModels[ usableModelsKeys[ self.pers[ "myprop" ].indexKey ] ];
                                //spawn the model
								model solid();
                                block = spawn("script_model", self.origin);
                                block setModel(model);
                                block.angles = self.pers[ "myprop" ].angles;
                                self iprintln("^1[MAPEDITOR] ^7Model spawned");
							}
							else if(self.pers["mode"] == "turret")
							{
								//redefine useablemodelkeys
								usableModelsKeys = GetArrayKeys( level.turretList );
								//get current model
								model = level.turretList[ usableModelsKeys[ self.pers[ "myprop" ].indexKey ] ];
								//turret code by JariZ.nl
								turret = spawnTurret( "auto_turret", self.origin, "auto_gun_turret_mp" );
								turret.turretType = "sentry";
								turret SetTurretType(turret.turretType);
								turret SetModel( model );
								turret.angles = self.pers["myprop"].angles;
								self iprintln("^1[MAPEDITOR] ^7Turret spawned");
							}
							else if (self.pers["mode"] == "collmodel")
							{
								//redefine useablemodelkeys
								usableModelsKeys = GetArrayKeys( level.collMapModels );
								//spawn code by JariZ.nl                            
                                //get current model
                                model = level.collMapModels[ usableModelsKeys[ self.pers[ "myprop" ].indexKey ] ];
                                //spawn the model
								model solid();
                                block = spawn("script_model", self.origin);
                                block setModel(model);
                                block.angles = self.pers[ "myprop" ].angles;
                                self iprintln("^1[MAPEDITOR] ^7Collision Model spawned");
							}
                    }
                if( self FragButtonPressed() && IsDefined( self.pers[ "myprop" ] ) )
                {
                        if(self.pers["mode"] == "normal")
						{
							self.pers[ "myprop" ].indexKey = self.pers[ "myprop" ].indexKey + 1;
							PrintLn( "HNS INDEX: " + self.pers[ "myprop" ].indexKey + "   MAX POS: " + level.MAX_USUABLE_MODELS );
							if( self.pers[ "myprop" ].indexKey >= level.MAX_USUABLE_MODELS || self.pers[ "myprop" ].indexKey < 0 )
							{
									self.pers[ "myprop" ].indexKey = 0;
							}
							model = level.usableModels[ usableModelsKeys[ self.pers[ "myprop" ].indexKey ] ];
							//self.modelNameHUD SetText( model );
							self.pers[ "myprop" ] SetModel( model );
							self.pers[ "myprop" ] NotSolid();
						}
						else if (self.pers["mode"] == "collmodel")
						{
							//redefine useablemodelkeys
							usableModelsKeys = GetArrayKeys( level.collMapModels );
							
							if(self.pers[ "myprop" ])
							self.pers[ "myprop" ].indexKey = self.pers[ "myprop" ].indexKey + 1;
							PrintLn( "HNS INDEX: " + self.pers[ "myprop" ].indexKey + "   MAX POS: " + level.MAX_COLL_MODELS );
							if( self.pers[ "myprop" ].indexKey >= level.MAX_COLL_MODELS || self.pers[ "myprop" ].indexKey < 0 )
							{
									self.pers[ "myprop" ].indexKey = 0;
							}
							model = level.collMapModels[ usableModelsKeys[ self.pers[ "myprop" ].indexKey ] ];
							//self.modelNameHUD SetText( model );
							self.pers[ "myprop" ] SetModel( model );
							self.pers[ "myprop" ] NotSolid();
						}
						else if (self.pers["mode"] == "turret")
						{
							//redefine useablemodelkeys
							usableModelsKeys = GetArrayKeys( level.turretList );
							
							if(self.pers[ "myprop" ])
							self.pers[ "myprop" ].indexKey = self.pers[ "myprop" ].indexKey + 1;
							PrintLn( "HNS INDEX: " + self.pers[ "myprop" ].indexKey + "   MAX POS: " + level.turretList.size );
							if( self.pers[ "myprop" ].indexKey >= level.turretList.size || self.pers[ "myprop" ].indexKey < 0 )
							{
									self.pers[ "myprop" ].indexKey = 0;
							}
							model = level.turretList[ usableModelsKeys[ self.pers[ "myprop" ].indexKey ] ];
							//self.modelNameHUD SetText( model );
							self.pers[ "myprop" ] SetModel( model );
							self.pers[ "myprop" ] NotSolid();
						}
                }
                if( self SecondaryOffhandButtonPressed() && IsDefined( self.pers[ "myprop" ] ) )
                {
						if(self.pers["mode"] == "normal")
						{
							self.pers[ "myprop" ].indexKey = self.pers[ "myprop" ].indexKey - 1;
							PrintLn( "HNS INDEX: " + self.pers[ "myprop" ].indexKey + "   MAX POS: " + level.MAX_USUABLE_MODELS );
							if( self.pers[ "myprop" ].indexKey >= level.MAX_USUABLE_MODELS || self.pers[ "myprop" ].indexKey < 0 )
							{
									self.pers[ "myprop" ].indexKey = 0;
							}
							model = level.usableModels[ usableModelsKeys[ self.pers[ "myprop" ].indexKey ] ];
							//self.modelNameHUD SetText( model );
							self.pers[ "myprop" ] SetModel( model );
							self.pers[ "myprop" ] NotSolid();
						}
						else if (self.pers["mode"] == "collmodel")
						{
							//redefine useablemodelkeys
							usableModelsKeys = GetArrayKeys( level.collMapModels );
							
							if(self.pers[ "myprop" ])
							self.pers[ "myprop" ].indexKey = self.pers[ "myprop" ].indexKey - 1;
							PrintLn( "HNS INDEX: " + self.pers[ "myprop" ].indexKey + "   MAX POS: " + level.MAX_COLL_MODELS );
							if( self.pers[ "myprop" ].indexKey >= level.MAX_COLL_MODELS || self.pers[ "myprop" ].indexKey < 0 )
							{
									self.pers[ "myprop" ].indexKey = 0;
							}
							model = level.collMapModels[ usableModelsKeys[ self.pers[ "myprop" ].indexKey ] ];
							//self.modelNameHUD SetText( model );
							self.pers[ "myprop" ] SetModel( model );
							self.pers[ "myprop" ] NotSolid();
						}
						else if (self.pers["mode"] == "turret")
						{
							//redefine useablemodelkeys
							usableModelsKeys = GetArrayKeys( level.turretList );
							
							if(self.pers[ "myprop" ])
							self.pers[ "myprop" ].indexKey = self.pers[ "myprop" ].indexKey - 1;
							PrintLn( "HNS INDEX: " + self.pers[ "myprop" ].indexKey + "   MAX POS: " + level.turretList.size );
							if( self.pers[ "myprop" ].indexKey >= level.turretList.size || self.pers[ "myprop" ].indexKey < 0 )
							{
									self.pers[ "myprop" ].indexKey = 0;
							}
							model = level.turretList[ usableModelsKeys[ self.pers[ "myprop" ].indexKey ] ];
							//self.modelNameHUD SetText( model );
							self.pers[ "myprop" ] SetModel( model );
							self.pers[ "myprop" ] NotSolid();
						}
                }
                if( self ActionSlotThreeButtonPressed() )
                {
                        if( GetDvarInt( "cg_thirdPersonRange" ) > minZoom )
                        {
                                self SetClientDvar( "cg_thirdPersonRange", GetDvarInt( "cg_thirdPersonRange" ) - zoomChangeRate );
                        }
                }
                if( self ActionSlotFourButtonPressed() )
                {
                        if( GetDvarInt( "cg_thirdPersonRange" ) < maxZoom )
                        {
                                self SetClientDvar( "cg_thirdPersonRange", GetDvarInt( "cg_thirdPersonRange" ) + zoomChangeRate );
                        }
                }
                self buttonHeldCheck( self.pers[ "myprop" ].rotateYaw_attack );
                self buttonHeldCheck( self.pers[ "myprop" ].rotateYaw_ads );
                self.pers[ "myprop" ] RotateYaw( self.pers[ "myprop" ].rotateYaw_ads.value + self.pers[ "myprop" ].rotateYaw_attack.value, 0.5 );
        }
 
}
 
switchSpawnMode( mode )
{
	self.pers["mode"] = mode; //switch mode
	self buildMode(); // restart buildmode
}
 
onPrecacheGameModels()
{
        precacheLevelModels();
        if( IsDefined( level.availableModels ) && level.availableModels.size > 0 )
        {
                level.availableModels = array_randomize( level.availableModels );
                if( level.availableModels.size < level.MAX_USUABLE_MODELS )
                {
                        level.MAX_USUABLE_MODELS = level.availableModels.size;
                }
                availableModelsKeys = GetArrayKeys( level.availableModels );
                if( !IsDefined( level.usableModels ) )
                {
                        level.usableModels = [];
                }
                for( x = 0 ; x < level.availableModels.size ; x++ )
                {
                        PreCacheModel( level.availableModels[ availableModelsKeys[ x ] ] );
                        level.usableModels[ level.availableModels[ availableModelsKeys[ x ] ] ] = level.availableModels[ availableModelsKeys[ x ] ];
                        if( level.usableModels.size >= level.MAX_USUABLE_MODELS )
                        {
                                return;
                        }
                }
        }
		else
		{
			iprintln("[me] loading models failed, no models assigned");
		}
		
}
 
adsCheck()
{
        return ( self AdsButtonPressed() );
}
 
attackCheck()
{
        return ( self AttackButtonPressed() );
}

addCollMapModel( model )
{
	if( !IsDefined( level.collMapModels ) )
	{
		level.collMapModels = [];
	}
	level.collMapModels[ model ] = model;
	
}

addModel( model )
{
        if( !IsDefined( level.availableModels ) )
        {
                level.availableModels = [];
        }
 
        if( IsDefined( level.collMapModels ) && IsDefined( level.collMapModels[ model ] ) )
        {
 
                return;
        }
        if( !IsDefined( level.availableModels[ model ] ) )
        {
                level.availableModels[ model ] = model;
        }
}

addTurret( model )
{
        if( !IsDefined( level.turretList ) )
        {
                level.turretList = [];
        }
		if( !IsDefined( level.turretList[ model ] ) )
        {
                level.turretList[ model ] = model;
        }
		
}
 
precacheLevelModels()
{
        if( IsDefined( level.force_hns_models ) )
        {
                [[ level.force_hns_models ]]();
                return;
        }
        switch( GetDvar( "mapname" ) )
        {
                case "mp_array":
                {
                        mpArrayPrecache();
                } break;
                case "mp_berlinwall2":
                {
                        mpBerlinwall2Precache();
                } break;
                case "mp_cairo":
                {
                        mpCairoPrecache();
                } break;
                case "mp_cosmodrome":
                {
                        mpCosmodromePrecache();
                } break;
                case "mp_cracked":
                {
                        mpCrackedPrecache();
                } break;
                case "mp_crisis":
                {
                        mpCrisisPrecache();
                } break;
                case "mp_discovery":
                {
                        mpDiscoveryPrecache();
                } break;
                case "mp_duga":
                {
                        mpDugaPrecache();
                } break;
                case "mp_firingrange":
                {
                        mpFiringrangePrecache();
                } break;
                case "mp_gridlock":
                {
                        mpGridlockPrecache();
                } break;
                case "mp_hanoi":
                {
                        mpHanoiPrecache();
                } break;
                case "mp_havoc":
                {
                        mpHavocPrecache();
                } break;
                case "mp_hotel":
                {
                        mpHotelPrecache();
                } break;
                case "mp_kowloon":
                {
                        mpKowloonPrecache();
                } break;
                case "mp_mountain":
                {
                        mpMountainPrecache();
                } break;
                case "mp_nuked":
                {
                        mpNukedPrecache();
                } break;
                case "mp_outskirts":
                {
                        mpOutskirtsPrecache();
                } break;
                case "mp_radiation":
                {
                        mpRadiationPrecache();
                } break;
                case "mp_russianbase":
                {
                        mpRussianbasePrecache();
                } break;
                case "mp_stadium":
                {
                        mpStadiumPrecache();
                } break;
                case "mp_villa":
                {
                        mpVillaPrecache();
                } break;
                case "mp_zoo":
                {
                        mpZooPrecache();
                } break;
        }
}
 

 
mapSupport()
{
        if( IsDefined( level.force_hns_support ) && level.force_hns_support )
        {
                return true;
        }
        switch( ToLower( GetDvar( "mapname" ) ) )
        {
                case "mp_array":
                case "mp_berlinwall2":
                case "mp_cairo":
                case "mp_cosmodrome":
                case "mp_cracked":
                case "mp_crisis":
                case "mp_discovery":
                case "mp_duga":
                case "mp_firingrange":
                case "mp_gridlock":
                case "mp_hanoi":
                case "mp_havoc":
                case "mp_hotel":
                case "mp_kowloon":
                case "mp_mountain":
                case "mp_nuked":
                case "mp_outskirts":
                case "mp_radiation":
                case "mp_russianbase":
                case "mp_stadium":
                case "mp_villa":
                case "mp_zoo":
                {
                        return true;
                }
        }
        return false;
}

onMenuResponse()
{
        self endon( "death" );
        self endon( "disconnect" );
       
        while( true )
        {
                self waittill( "menuresponse", menu, response );
				
				//cmd
				if(response == "fpsmode")
				{
					self fpsMode();
				}
				else if(response == "buildmode")
				{
					self buildMode();
				}
				else if(response == "controls")
				{
				    self openMenu( "me_controls" );
				}
				else if(response == "switchto" )
				{
					if( !IsDefined( self.pers[ "myprop" ]  ) )
					{
						//user isn't in build mode, switch to build mode
						buildMode();
					}
					self openMenu( "me_switchto" );
				}
				else if(response == "save")
				{
					MapEditor_Save_Beta();
				}
				
				//switchto
				else if(response == "switch_turret")
				{
					self switchSpawnMode("turret");
				}
				else if(response == "switch_normal")
				{
					self switchSpawnMode("normal");
				}
				else if(response == "switch_collmodel")
				{
					self switchSpawnMode("collmodel");
				}
				
				//start
				else if(response == "buildmode")
				{
					self BuildMode();
				}
        }
}

menu()
{
    self endon( "disconnect" );
    self endon( "killed_player" );
    self endon( "death" );
    level endon( "game_ended" );
	
	while(1)
	{
			if(self UseButtonPressed())
                {
                          self openmenu( "me_cmd" );             
                }
	    wait 0.01;
	}
}	
